package com.qlyl.modules.information.ethadapter;

import com.qlyl.modules.information.service.IEthTransactionService;
import com.senlin.ethereum.core.EthClient;
import com.senlin.ethereum.core.EthEvent;
import com.senlin.ethereum.infura.InfuraClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.web3j.protocol.core.methods.response.TransactionReceipt;

import java.util.Arrays;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * @author huwei
 */
@Slf4j
@Component
public class TransactionReceiptTimeLoop {

    @Autowired
    private EthClient ethClient;

    @Autowired
    private EthRedisCache redisCache;

    @Autowired
    private IEthTransactionService iEthTransactionService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private InfuraClient.Ropsten ropstenClient;

    @Scheduled(cron = "0 */1 * * * *")
    public void loopCheck() {
        log.info("===> Transaction检测上链定时任务执行 ->");
        ethClient.handleTransactionReceipt(() -> {
            // 获取相应的未验证的交易Hash
            return redisCache.popsTransactionHash(10L);

        }, new EthEvent<TransactionReceipt, String>() {

            @Override
            public void onSuccess(TransactionReceipt transactionReceipt) {
                // 此处代表此次交易Hash已上链，
                String transactionHash = transactionReceipt.getTransactionHash();
                log.info("=====> 上链成功！交易Hash为：{}", transactionHash);
                // 修改数据库上链状态
                iEthTransactionService.modifyStatusOnSuccess(transactionHash);
            }

            @Override
            public void onPending(String s) {
                log.info("=====> 上链中！交易Hash为：{}", s);
                redisCache.putTransactionHash(s);
            }

            @Override
            public void onExcept(String s, Exception e) {
                log.info("=====> 查询失败！交易Hash为：{}", s, e);
                redisCache.putTransactionHash(s);
            }
        });
    }

    @Scheduled(cron = "0 */20 * * * *")
    public void loopDonate() {
        String address = (String) redisTemplate.opsForList().leftPop(EthConst.INFURA_ROPSTEN_DONATE_REDIS_KEY, 1, TimeUnit.SECONDS);
        if (address == null) return;

        Optional<InfuraClient.RopstenDonate> ropstenDonate = ropstenClient.requestAndGetEther(address);
        if (!ropstenDonate.isPresent())
            redisTemplate.opsForList().leftPush(EthConst.INFURA_ROPSTEN_DONATE_REDIS_KEY, address);
    }
}
